package com.xbongbong.pay.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.TwoDimensionCodeEncoder;
import com.xbongbong.pay.exception.PayApiException;
import com.xbongbong.pay.platform.alipay.utils.AliPayApi;
import com.xbongbong.pay.platform.unionpay.config.UnionPayConfig;
import com.xbongbong.pay.platform.unionpay.config.UnionPayMetaContainer;
import com.xbongbong.pay.platform.unionpay.pojo.request.UnionPayBackTransRequest;
import com.xbongbong.pay.platform.unionpay.pojo.request.UnionPayFrontTransRequest;
import com.xbongbong.pay.platform.unionpay.utils.UnionPayApi;
import com.xbongbong.pay.platform.wechatpay.pojo.request.partner.WeChatPayPartnerH5TransactionsRequest;
import com.xbongbong.pay.platform.wechatpay.pojo.request.partner.WeChatPayPartnerNativeTransactionsRequest;
import com.xbongbong.pay.platform.wechatpay.pojo.request.partner.WeChatPayPartnerTransactionsRequest;
import com.xbongbong.pay.platform.wechatpay.pojo.response.partner.WeChatPayOrderNoticeResource;
import com.xbongbong.pay.platform.wechatpay.pojo.response.partner.WeChatPayOrderNoticeResponse;
import com.xbongbong.pay.platform.wechatpay.pojo.response.partner.WeChatPayPartnerH5TransactionsResponse;
import com.xbongbong.pay.platform.wechatpay.pojo.response.partner.WeChatPayPartnerNativeTransactionsResponse;
import com.xbongbong.pay.platform.wechatpay.pojo.response.partner.WeChatPayPartnerTransactionsResponse;
import com.xbongbong.pay.platform.wechatpay.utils.WeChatPayApi;
import com.xbongbong.pay.platform.wechatpay.utils.WeChatPayPartnerApi;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author 魏荣杰
 * @date 2021/1/21 15:21
 * @since
 * @version
 */
@RestController
@RequestMapping( "/pay/test")
public class PayTestController {
    private static final Logger LOG = LoggerFactory.getLogger(PayTestController.class);

    @Resource
    private UnionPayMetaContainer unionPayMetaContainer;
    @Resource
    private UnionPayConfig unionPayConfig;
    @Resource
    private UnionPayApi unionPayApi;
    @Resource
    private AliPayApi aliPayApi;
    @Resource
    private WeChatPayApi weChatPayApi;
    @Resource
    private WeChatPayPartnerApi weChatPayPartnerApi;

    @RequestMapping(value = "/testConfig", method = RequestMethod.POST)
    public void test() {
//        LOG.error("++++++++++++++++aaaaaaaaaaa");
        LOG.error("==========" + JSON.toJSONString(unionPayConfig));
        LOG.error("+++/+++++++++++++" + JSON.toJSONString(unionPayMetaContainer));
        LOG.error("+++/+++++++++++++" + JSON.toJSONString(unionPayMetaContainer.getUnionPayMeta("test")));
        LOG.error("+++/+++++++++++++" + JSON.toJSONString(unionPayMetaContainer.getUnionPayMeta("test").getKeyStore()));
        LOG.error("===========" + JSON.toJSONString(unionPayMetaContainer));

    }

    @RequestMapping(value = "/unionPayFrontTrans", method = RequestMethod.GET)
    public CloseableHttpResponse unionPayFrontTrans() throws PayApiException {
        long date = DateTimeUtil.getLong();
        UnionPayFrontTransRequest request = new UnionPayFrontTransRequest();
        request.setBizType("000201");
        request.setTxnTime(DateTimeUtil.getString(date, DateTimeUtil.SDF_NoFormat));
        request.setCurrencyCode("156");
        request.setTxnAmt("1");
        request.setTxnType("01");
        request.setTxnSubType("01");
        request.setAccessType("0");
//        request.setSignature();
        request.setSignMethod("01");
        request.setChannelType("07");
        request.setMerId("777290058188811");
        request.setOrderId(String.valueOf(DateTimeUtil.getLong()));
        request.setPayTimeout(DateTimeUtil.getString(date + 15*60*1000, DateTimeUtil.SDF_NoFormat));
        request.setFrontUrl("https://www.baidu.com");
//        request.setCertId();

        return unionPayApi.frontTransSync(request, "777290058188811");
    }

    @RequestMapping(value = "/unionPayBackTransSync", method = RequestMethod.GET)
    public CloseableHttpResponse unionPayBackTransSync() throws PayApiException {
        long date = DateTimeUtil.getLong();
        UnionPayBackTransRequest request = new UnionPayBackTransRequest();
        request.setBizType("000201");
        request.setTxnTime(DateTimeUtil.getString(date, DateTimeUtil.SDF_NoFormat));
//        request.setCurrencyCode("156");
        request.setTxnAmt("1");
        request.setTxnType("31");
        request.setTxnSubType("00");
        request.setAccessType("0");
//        request.setSignature();
        request.setSignMethod("01");
        request.setChannelType("07");
        request.setMerId("777290058188811");
//        request.setOrderId();
//        request.setOrigQryId();
//        request.setCertId();

        return unionPayApi.backTransSync(request, "777290058188811");
    }

    @RequestMapping(value = "/alipayTradePrecreate", method = RequestMethod.GET)
    public String alipayTradePrecreate() throws PayApiException, AlipayApiException {
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setSubject("测试1");
        model.setOutTradeNo(String.valueOf(DateTimeUtil.getLong()));
        model.setTotalAmount("0.01");
        model.setProductCode("1");

        AlipayTradePrecreateResponse alipayTradePrecreateResponse = aliPayApi.tradePrecreate(model, null, null, "2088621955219488");
        return alipayTradePrecreateResponse.getBody();
    }

    @RequestMapping(value = "/alipayTradeWapPay", method = RequestMethod.GET)
    public String alipayTradeWapPay() throws PayApiException, AlipayApiException {
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setSubject("测试1");
        model.setOutTradeNo(String.valueOf(DateTimeUtil.getLong()));
        model.setTotalAmount("0.01");
        model.setQuitUrl("http://www.baidu.com");
        model.setProductCode("1");

        AlipayTradeWapPayResponse alipayTradeWapPayResponse = aliPayApi.wapPay(model, null, null, null, "2088621955219488");
        return alipayTradeWapPayResponse.getBody();
    }

    @RequestMapping(value = "/alipayTradeWapPay/notice", method = RequestMethod.POST)
    public void alipayTradeWapPayNotice(HttpServletRequest request) throws AlipayApiException {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        String publcCertPath = "";
        // 校验
        boolean rsa2 = AlipaySignature.certVerifyV1(params, publcCertPath, "UTF-8", "RSA2");
        // 成功更新数据
//        request.getParameterMap()
//        AlipaySignature.
    }

    @RequestMapping(value = "/alipayTradePagePay", method = RequestMethod.GET)
    public String alipayTradePagePay() throws PayApiException, AlipayApiException {
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(String.valueOf(DateTimeUtil.getLong()));
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        model.setTotalAmount("0.01");
        model.setSubject("测试");
//        model.setTimeExpire(DateTimeUtil.getString(DateTimeUtil.getInt() + 86400, DateTimeUtil.SDF));
        model.setTimeoutExpress("1h");


        AlipayTradePagePayResponse alipayTradePagePayResponse = aliPayApi.tradePagePay(model, null, "http://rajers.vaiwan.com/pay/test/alipayTradeWapPay/notice", null, "2088621955219488");
        return alipayTradePagePayResponse.getBody();
    }

    @RequestMapping(value = "/alipayTradeRefund", method = RequestMethod.POST)
    public String alipayTradeRefund() throws AlipayApiException {
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo("1612429548104");
        model.setTradeNo("2021020422001487350504890457");
        model.setRefundAmount("0.01");
//        model.setRefundCurrency("CNY");
        AlipayTradeRefundResponse alipayTradeRefundResponse = aliPayApi.tradeRefund(model, null, "2088621955219488");
        return alipayTradeRefundResponse.getBody();
    }

    @RequestMapping(value = "/wechatPayOrder", method = RequestMethod.GET)
    public void wechatPayOrder() throws PayApiException, AlipayApiException {
        WeChatPayPartnerTransactionsRequest request = new WeChatPayPartnerTransactionsRequest();
        request.setSpAppId("wxf3504bef10dcdb71");
        request.setSpMchId("1520631141");
        request.setSubMchId("1606610691");
        request.setDescription("测试");
        request.setOutTradeNo(String.valueOf(DateTimeUtil.getLong()));
//        request.setTimeExpire();
//        request.setAttach();
        request.setNotifyUrl("https://www.baidu.com");
//        request.setGoodsTag();

        request.setAmount( new WeChatPayPartnerTransactionsRequest.Amount(1, "CNY"));
        WeChatPayPartnerTransactionsRequest.Payer payer = new WeChatPayPartnerTransactionsRequest.Payer();
        payer.setSubOpenId("oomRg5XeqIb08EbPTMBpAStUlyxo");
        request.setPayer(payer);
//        WeChatPayPartnerTransactionsRequest.SceneInfo sceneInfo = new WeChatPayPartnerTransactionsRequest.SceneInfo();
//        sceneInfo.setPayerClientIp("14.23.150.211");
//        request.setSceneInfo(sceneInfo);
        WeChatPayPartnerTransactionsResponse order = weChatPayPartnerApi.orderForJsapi(request, "1520631141");
        //WeChatUnifiedOrderResponse order = weChatPayApi.order(request, "1520631141");
        System.out.println(JSON.toJSONString(order));
//        wx19192715778804784b28369afd89e90000
//        wx19195432350718b8e1ebd5f684ac820000
    }

    @RequestMapping(value = "/wechatPayOrder/notice", method = RequestMethod.POST)
    public void wechatPayOrderNotice(HttpServletRequest request) throws Exception {
        BufferedReader br = null;
        StringBuilder result = new StringBuilder();
        try {
            br = request.getReader();
            for (String line; (line = br.readLine()) != null; ) {
                if (result.length() > 0) {
                    result.append("\n");
                }
                result.append(line);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        WeChatPayOrderNoticeResponse weChatPayOrderNoticeResponse = JSON.parseObject(result.toString(), WeChatPayOrderNoticeResponse.class);
        WeChatPayOrderNoticeResponse.Resource resource = weChatPayOrderNoticeResponse.getResource();

        // 解密 v3密钥
        AesUtil aesUtil = new AesUtil("IqgH145ReMlO0ftVbAODCO4ewhVeMTmy".getBytes(StandardCharsets.UTF_8));
        String decryptToString = aesUtil.decryptToString(resource.getAssociatedData().getBytes(StandardCharsets.UTF_8), resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
        // 明文信息
        WeChatPayOrderNoticeResource weChatPayOrderNoticeResource = JSON.parseObject(decryptToString, WeChatPayOrderNoticeResource.class);

        System.out.println(JSON.toJSONString(weChatPayOrderNoticeResponse));
        System.out.println(JSON.toJSONString(result.toString()));
    }


    @RequestMapping(value = "/wechatPayOrderH5", method = RequestMethod.GET)
    public void wechatPayOrderH5() throws PayApiException, AlipayApiException {
        WeChatPayPartnerH5TransactionsRequest request = new WeChatPayPartnerH5TransactionsRequest();
        request.setSpAppId("wxf3504bef10dcdb71");
        request.setSpMchId("1520631141");
        request.setSubMchId("1606610691");
        request.setDescription("测试");
        request.setOutTradeNo(String.valueOf(DateTimeUtil.getLong()));
//        request.setTimeExpire();
//        request.setAttach();
        request.setNotifyUrl("https://www.baidu.com");
//        request.setGoodsTag();

        request.setAmount( new WeChatPayPartnerH5TransactionsRequest.Amount(1, "CNY"));

        WeChatPayPartnerH5TransactionsRequest.SceneInfo sceneInfo = new WeChatPayPartnerH5TransactionsRequest.SceneInfo();
        WeChatPayPartnerH5TransactionsRequest.SceneInfo.H5Info h5Info = new WeChatPayPartnerH5TransactionsRequest.SceneInfo.H5Info();
        h5Info.setType("Wap");
        sceneInfo.setPayerClientIp("14.23.150.211");
        sceneInfo.setH5Info(h5Info);
        request.setSceneInfo(sceneInfo);
        WeChatPayPartnerH5TransactionsResponse order = weChatPayPartnerApi.orderForH5(request, "1520631141");
        System.out.println(JSON.toJSONString(order));
    }

    @RequestMapping(value = "/wechatPayOrderNative", method = RequestMethod.GET)
    public void wechatPayOrderNative() throws Exception {
        WeChatPayPartnerNativeTransactionsRequest request = new WeChatPayPartnerNativeTransactionsRequest();
        request.setSpAppId("wxf3504bef10dcdb71");
        request.setSpMchId("1520631141");
        request.setSubMchId("1606610691");
        request.setDescription("测试");
        request.setOutTradeNo(String.valueOf(DateTimeUtil.getLong()));
//        request.setTimeExpire();
//        request.setAttach();
        request.setNotifyUrl("https://www.baidu.com");
//        request.setGoodsTag();

        request.setAmount( new WeChatPayPartnerNativeTransactionsRequest.Amount(1, "CNY"));

        WeChatPayPartnerNativeTransactionsRequest.SceneInfo sceneInfo = new WeChatPayPartnerNativeTransactionsRequest.SceneInfo();
        sceneInfo.setPayerClientIp("14.23.150.211");
        request.setSceneInfo(sceneInfo);
        WeChatPayPartnerNativeTransactionsResponse order = weChatPayPartnerApi.orderForNative(request, "1520631141");

        BufferedImage qrCode = TwoDimensionCodeEncoder.get2DCode(order.getCodeUrl(), 180, 180);
        byte[] qrCodeBytes = TwoDimensionCodeEncoder.BufferedImage2Bytes(qrCode);
         /*
            base64 要求每76个字符加回车换行，我们返回前端的图片base64不能带回车换行，
            使用apache codec 的 Base64工具类不会出现回车换行，其他工具类可能出现回车换行
             */
        String qrCodeBase64 = Base64.encodeBase64String(qrCodeBytes);
        System.out.println(qrCodeBase64);
    }
}
